﻿using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using UCL.Powersource.Statistics;
using UCL.Powersource;

namespace Powersource_UnitTests.StatisticsTest
{
    /// <summary>
    /// Summary description for PBckLogItemsDoneTest
    /// </summary>
    [TestClass]
    public class WIStatisticsTests
    {

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //

        #endregion

        private PBckLogItemsDone stat;
        private TotalEffortDone tedstat;
        private FinishDateTotalEffort fdestat;
        private StartDateTotalEffort sdestat;
        private MockTfsTeamProjectCollConfig tfsTPCollConfig;
        private msp1MockTfsTeamProjectCollConfig msptfsTPCollConfig;
        private InvalidTasks istat;
        private InvalidPBckLogItems ipstat;
        private DonePBITestsNumb dtnstat;
        private PBIwithNoTests pntstat;
        private VelocityStatistics velstat;
        private AccelerationStatistics acstat;
        private PercentageOfPlannedEffortDone percstat;
  
        // Use TestInitialize to run code before running each test 
        [TestInitialize()]
        public void MyTestInitialize() 
        {
            tfsTPCollConfig = new MockTfsTeamProjectCollConfig();
            stat = new PBckLogItemsDone();
            msptfsTPCollConfig = new msp1MockTfsTeamProjectCollConfig();
            tedstat = new TotalEffortDone();
            sdestat = new StartDateTotalEffort();
            fdestat = new FinishDateTotalEffort();
            istat = new InvalidTasks();
            ipstat = new InvalidPBckLogItems();
            dtnstat = new DonePBITestsNumb();
            pntstat = new PBIwithNoTests();
            velstat = new VelocityStatistics();
            acstat = new AccelerationStatistics();
            percstat = new PercentageOfPlannedEffortDone();
        }

        // Use TestCleanup to run code after each test has run
        [TestCleanup()]
        public void MyTestCleanup() 
        {
            tfsTPCollConfig = null;
            stat = null;
            msptfsTPCollConfig = null;
            tedstat = null;
            fdestat = null;
            sdestat = null;
            istat = null;
            ipstat = null;
            dtnstat = null;
            pntstat = null;
            velstat = null;
            acstat = null;
            percstat = null;
        }
        
        [TestMethod]
        public void PBckLogItemsDoneCount()
        {
            var proj1 = tfsTPCollConfig.TeamProjectConfigurations[0];
            var timeframe = tfsTPCollConfig._ProjectCollectionTimeFrames[0] as TimeFrameIteration;
            var timeframe2 = tfsTPCollConfig._ProjectCollectionTimeFrames[1] as TimeFrameIteration;
            var timeframe3 = tfsTPCollConfig._ProjectCollectionTimeFrames[2] as TimeFrameIteration;
            var timeframe4 = tfsTPCollConfig._ProjectCollectionTimeFrames[3] as TimeFrameIteration;
           

            //sprint 2, AsOf final date
            stat.Resolve(proj1, timeframe);
            Assert.IsNotNull(stat.TeamResults[proj1][timeframe].Value, "Null value for {0}:{1} in TeamResults", proj1.UniqueName, timeframe.Label);
            Assert.AreEqual(4, stat.TeamResults[proj1][timeframe].Value, "Incorrect value for PBckLogItemsDone {0}:{1} in TeamResults", proj1.UniqueName, timeframe.Label);
            //sprint 3, AsOf final date
            stat.Resolve(proj1, timeframe2);
            Assert.IsNotNull(stat.TeamResults[proj1][timeframe2].Value, "Null value for {0}:{1} in TeamResults", proj1.UniqueName, timeframe2.Label);
            Assert.AreEqual(2, stat.TeamResults[proj1][timeframe2].Value, "Incorrect value for PBckLogItemsDone {0}:{1} in TeamResults", proj1.UniqueName, timeframe2.Label);
            //sprint 2, AsOf sprint3 final date
            stat.Resolve(proj1, timeframe3);
            Assert.IsNotNull(stat.TeamResults[proj1][timeframe3].Value, "Null value for {0}:{1} in TeamResults", proj1.UniqueName, timeframe3.Label);
            Assert.AreEqual(4, stat.TeamResults[proj1][timeframe3].Value, "Incorrect value for PBckLogItemsDone {0}:{1} in TeamResults", proj1.UniqueName, timeframe3.Label);
            //sprint 3, AsOf date within the sprint
            stat.Resolve(proj1, timeframe4);
            Assert.IsNotNull(stat.TeamResults[proj1][timeframe4].Value, "Null value for {0}:{1} in TeamResults", proj1.UniqueName, timeframe4.Label);
            Assert.AreEqual(0, stat.TeamResults[proj1][timeframe4].Value, "Incorrect value for PBckLogItemsDone {0}:{1} in TeamResults", proj1.UniqueName, timeframe4.Label);
          

        }

        [TestMethod]
        public void WIStateStatsInvalIterationPath()
        {
            var proj1 = tfsTPCollConfig.TeamProjectConfigurations[0];
            var InvalidPathtimeframe = (TimeFrameIteration)tfsTPCollConfig._ProjectCollectionTimeFrames[4] as TimeFrameIteration;

            stat.Resolve(proj1, InvalidPathtimeframe);
            Assert.IsNull(stat.TeamResults[proj1][InvalidPathtimeframe].Value, "Not Null for Project {0} for an inavlid Iteration Path {1} in TeamResults", proj1.UniqueName, InvalidPathtimeframe.IterationPath);
        }

        [TestMethod]
        public void TestMultipleProjectsStatistics()
        {
            var proj1 = msptfsTPCollConfig.TeamProjectConfigurations[1];
            var proj2 = msptfsTPCollConfig.TeamProjectConfigurations[2];
            var proj3 = msptfsTPCollConfig.TeamProjectConfigurations[3];
            var proj4 = msptfsTPCollConfig.TeamProjectConfigurations[4];

            var timeframe1 = msptfsTPCollConfig._ProjectCollectionTimeFrames[0] as TimeFrameIteration;
            var timeframe2 = msptfsTPCollConfig._ProjectCollectionTimeFrames[1] as TimeFrameIteration;

            stat.Resolve(proj2, timeframe2);
            Assert.AreEqual(5,stat.TeamResults[proj2][timeframe2].Value, "Not Null for Project {0} for PBckLogItemsDone {1} in TeamResults", proj2.UniqueName, timeframe2);

            stat.Resolve(proj1, timeframe2);
            Assert.AreEqual(0, stat.TeamResults[proj1][timeframe2].Value, "Not Null for Project {0} for PBckLogItemsDone {1} in TeamResults", proj1.UniqueName, timeframe2);


        }

        [TestMethod]
        public void SameProjectNameDiffCollStat()
        {
            var proj1 = tfsTPCollConfig.TeamProjectConfigurations[0];
            var proj2 = msptfsTPCollConfig.TeamProjectConfigurations[0];

            var timeframe = msptfsTPCollConfig._ProjectCollectionTimeFrames[2] as TimeFrameIteration;

            stat.Resolve(proj1, timeframe);
            stat.Resolve(proj2, timeframe);

            Assert.AreNotEqual(stat.TeamResults[proj1][timeframe].Value, stat.TeamResults[proj2][timeframe].Value, "Incorrect value for {0}:{1} in collection {2} in TeamResults", proj2.UniqueName, timeframe.Label, msptfsTPCollConfig.Uri);

        }

        [TestMethod]
        public void EffortStatisticsTest()
        {

            var proj1 = msptfsTPCollConfig.TeamProjectConfigurations[2];
            var proj2 = msptfsTPCollConfig.TeamProjectConfigurations[4];

            var proj = tfsTPCollConfig.TeamProjectConfigurations[0];
            var timeframe = tfsTPCollConfig._ProjectCollectionTimeFrames[0] as TimeFrameIteration;

            var timeframe1 = msptfsTPCollConfig._ProjectCollectionTimeFrames[0] as TimeFrameIteration;
            var timeframe2 = msptfsTPCollConfig._ProjectCollectionTimeFrames[1] as TimeFrameIteration;

            tedstat.Resolve(proj1, timeframe1);
            Assert.IsNotNull(tedstat.TeamResults[proj1][timeframe1].Value, "Null value for {0}:{1} in collection {2} in TeamResults", proj1.UniqueName, timeframe1.Label, msptfsTPCollConfig.Uri);
            Assert.AreEqual(26, tedstat.TeamResults[proj1][timeframe1].Value, "Incorrect value for total effort done for {0}:{1} in collection {2} in TeamResults", proj1.UniqueName, timeframe1.Label, msptfsTPCollConfig.Uri);

            tedstat.Resolve(proj, timeframe);
            Assert.IsNotNull(tedstat.TeamResults[proj][timeframe].Value, "Null value for {0} in collection {1} in TeamResults", proj.UniqueName, tfsTPCollConfig.Uri);
            Assert.AreEqual(42, tedstat.TeamResults[proj][timeframe].Value, "Incorrect value for total effort done for {0} in collection {1} in TeamResults", proj.UniqueName, tfsTPCollConfig.Uri);

            sdestat.Resolve(proj, timeframe);
            Assert.IsNotNull(sdestat.TeamResults[proj][timeframe].Value, "Null value for {0} in collection {1} in TeamResults", proj.UniqueName, tfsTPCollConfig.Uri);
            Assert.AreEqual(42, sdestat.TeamResults[proj][timeframe].Value, "Incorrect value for start date total effort for {0} in collection {1} in TeamResults", proj.UniqueName, tfsTPCollConfig.Uri);

            fdestat.Resolve(proj, timeframe);
            Assert.IsNotNull(fdestat.TeamResults[proj][timeframe].Value, "Null value for {0} in collection {1} in TeamResults", proj.UniqueName, tfsTPCollConfig.Uri);
            Assert.AreEqual(42, fdestat.TeamResults[proj][timeframe].Value, "Incorrect value for final date total effort for {0} in collection {1} in TeamResults", proj.UniqueName, tfsTPCollConfig.Uri);

            sdestat.Resolve(proj2, timeframe1);
            Assert.IsNotNull(sdestat.TeamResults[proj2][timeframe1].Value, "Null value for {0}:{1} in collection {2} in TeamResults", proj2.UniqueName, timeframe1.Label, msptfsTPCollConfig.Uri);
            Assert.AreEqual(23, sdestat.TeamResults[proj2][timeframe1].Value, "Incorrect value for start day total effort for {0}:{1} in collection {2} in TeamResults", proj2.UniqueName, timeframe1.Label, msptfsTPCollConfig.Uri);

            fdestat.Resolve(proj2, timeframe1);
            Assert.IsNotNull(fdestat.TeamResults[proj2][timeframe1].Value, "Null value for {0}:{1} in collection {2} in TeamResults", proj2.UniqueName, timeframe1.Label, msptfsTPCollConfig.Uri);
            Assert.AreEqual(23, fdestat.TeamResults[proj2][timeframe1].Value, "Incorrect value for final day total effort for {0}:{1} in collection {2} in TeamResults", proj2.UniqueName, timeframe1.Label, msptfsTPCollConfig.Uri);

            tedstat.Resolve(proj2, timeframe1);
            Assert.IsNotNull(tedstat.TeamResults[proj2][timeframe1].Value, "Null value for {0}:{1} in collection {2} in TeamResults", proj2.UniqueName, timeframe1.Label, msptfsTPCollConfig.Uri);
            Assert.AreEqual(23, tedstat.TeamResults[proj2][timeframe1].Value, "Incorrect value for total effort done for {0}:{1} in collection {2} in TeamResults", proj2.UniqueName, timeframe1.Label, msptfsTPCollConfig.Uri);

        }

        [TestMethod]
        public void PercentageEffortTest()
        {
            var proj = tfsTPCollConfig.TeamProjectConfigurations[0];
            var timeframe = tfsTPCollConfig._ProjectCollectionTimeFrames[0] as TimeFrameIteration;

            percstat.Resolve(proj, timeframe);
            Assert.IsNotNull(percstat.TeamResults[proj][timeframe].Value, "Null value for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);
            Assert.AreEqual(1, percstat.TeamResults[proj][timeframe].Value, "Incorrect value for PercentageOfPlannedEffortDone for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);
 
        }

        [TestMethod]
        public void InvalidTasksTest()
        {
            var proj = tfsTPCollConfig.TeamProjectConfigurations[0];
            var timeframe = tfsTPCollConfig._ProjectCollectionTimeFrames[0] as TimeFrameIteration;

            istat.Resolve(proj, timeframe);
            Assert.IsNotNull(istat.TeamResults[proj][timeframe].Value, "Null value for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);
            Assert.AreEqual(16, istat.TeamResults[proj][timeframe].Value, "Incorrect value for inavlid tasks for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);
        }

        [TestMethod]
        public void LinksRelatedStatisticsTests()
        {
            var proj = msptfsTPCollConfig.TeamProjectConfigurations[2];
            var timeframe = msptfsTPCollConfig._ProjectCollectionTimeFrames[0] as TimeFrameIteration;

            dtnstat.Resolve(proj, timeframe);
            Assert.IsNotNull(dtnstat.TeamResults[proj][timeframe].Value, "Null value for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);
            Assert.AreEqual(5, dtnstat.TeamResults[proj][timeframe].Value, "Incorrect value for DonePBITestsNumb for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);

            ipstat.Resolve(proj, timeframe);
            Assert.IsNotNull(ipstat.TeamResults[proj][timeframe].Value, "Null value for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);
            Assert.AreEqual(5, ipstat.TeamResults[proj][timeframe].Value, "Incorrect value for InvalidPBckLogItems for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);

            istat.Resolve(proj, timeframe);
            Assert.IsNotNull(istat.TeamResults[proj][timeframe].Value, "Null value for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);
            Assert.AreEqual(12, istat.TeamResults[proj][timeframe].Value, "Incorrect value for InvalidTasks for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);

            pntstat.Resolve(proj, timeframe);
            Assert.IsNotNull(pntstat.TeamResults[proj][timeframe].Value, "Null value for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);
            Assert.AreEqual(0, pntstat.TeamResults[proj][timeframe].Value, "Incorrect value for PBIwithNoTests for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);    
        }

        [TestMethod]
        public void VelocityTests()
        {
            var proj = tfsTPCollConfig.TeamProjectConfigurations[0];
            var timeframe = tfsTPCollConfig._ProjectCollectionTimeFrames[0] as TimeFrameIteration;
            var timeframe1 = tfsTPCollConfig._ProjectCollectionTimeFrames[4] as TimeFrameIteration;

            velstat.Resolve(proj, timeframe);
            Assert.IsNotNull(velstat.TeamResults[proj][timeframe].Value, "Null value for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);
            Assert.AreEqual(42, velstat.TeamResults[proj][timeframe].Value, "Incorrect value for velocity for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);    

            acstat.Resolve(proj, timeframe);
            Assert.IsNotNull(acstat.TeamResults[proj][timeframe].Value, "Null value for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);
            Assert.AreEqual(0.2, acstat.TeamResults[proj][timeframe].Value, "Incorrect value for acceleration for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);

            acstat.Resolve(proj, timeframe1);
            Assert.IsNull(acstat.TeamResults[proj][timeframe1].Value, "Expected null value for invalid iteration path for {0}:{1} in TeamResults", proj.UniqueName, timeframe1.Label);

        }

        [TestMethod]
        public void NullTimeFrameDatesTest()
        {
            var proj = tfsTPCollConfig.TeamProjectConfigurations[0];
            var timeframe = tfsTPCollConfig._ProjectCollectionTimeFrames[7] as TimeFrameIteration;

            dtnstat.Resolve(proj, timeframe);
            Assert.IsNull(dtnstat.TeamResults[proj][timeframe].Value, "Expected null value for dtnstat for invalid time frame with null dates for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);
            tedstat.Resolve(proj, timeframe);
            Assert.IsNull(tedstat.TeamResults[proj][timeframe].Value, "Expected null value for tedstat for invalid time frame with null dates for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);
            stat.Resolve(proj, timeframe);
            Assert.IsNull(stat.TeamResults[proj][timeframe].Value, "Expected null value for tf for invalid time frame with null dates for {0}:{1} in TeamResults", proj.UniqueName, timeframe.Label);


        }
    }
}
